package com.fhzn.auth.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fhzn.auth.constant.Constants;
import com.fhzn.auth.entity.*;
import com.fhzn.auth.enums.WebResponseEnum;
import com.fhzn.auth.mapper.UserRoleMapper;
import com.fhzn.auth.service.UserRoleService;
import com.fhzn.auth.tools.AuthUtil;
import com.fhzn.auth.tools.UserManager;
import com.fhzn.auth.web.request.UserRoleRequest;
import com.fhzn.commons.toolkit.exception.BuzException;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 老顾
 * @apiNote
 * @since 2023/12/22
 */
@Service
@RequiredArgsConstructor
public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> implements UserRoleService {

    private final UserManager userManager;
    private final OperateLogManager operateLogManager;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String addRole(UserRoleRequest addRequest) {
        if (addRequest != null) {
            this.preCheck(addRequest);
            User userInfo = userManager.getUser(addRequest.getTargetUser());
            List<Role> operatorRoles = userManager.getRolesInDb(addRequest.getOperatorUser());
            if (!AuthUtil.canOperateRole(operatorRoles)) {
                throw new BuzException("没有给用户添加角色的权限");
            }
            List<Integer> realAddRoleIds = this.realAddRoles(addRequest);
            if (CollectionUtils.isEmpty(realAddRoleIds)) {
                throw new BuzException("无需给用户添加角色");
            }
            userManager.addRoleRelationBatch(realAddRoleIds, userInfo.getId(), addRequest.getOperatorUser());
            operateLogManager.onUserRoleChange(addRequest);
        }
        return WebResponseEnum.SUCCESS.getMessage();
    }

    private List<Integer> realAddRoles(UserRoleRequest request) {
        String handler = request.getOperatorUser();
        String targetUser = request.getTargetUser();
        List<Integer> targetRoleIds = request.getRoleIds();
        User user = userManager.getUser(targetUser);
        List<Role> operatorRoles = userManager.getCanOperatorRoles(handler, user.getId());
        List<Role> targetUserRolesInDb = userManager.getRolesInDb(targetUser);

        List<Integer> operatorRoleIds = operatorRoles.stream().map(Role::getId).collect(Collectors.toList());

        List<Integer> targetUserRoleIds = targetUserRolesInDb.stream().map(Role::getId).collect(Collectors.toList());

        List<Integer> canOperatorRoleIds = userManager.canOperatorRoles(targetRoleIds, operatorRoleIds);
        return userManager.realAddRoles(canOperatorRoleIds, targetUserRoleIds);
    }

    private void preCheck(UserRoleRequest request) {
        String handler = request.getOperatorUser();
        User targetUser = userManager.getUser(request.getTargetUser());
        User operatorUser = userManager.getUser(handler);

        if (targetUser == null || targetUser.getStatus() == null || targetUser.getStatus() == Constants.DISABLE) {
            throw new BuzException("被操作者不存在或者被禁用了");
        }
        if (operatorUser == null || operatorUser.getStatus() == null || operatorUser.getStatus() == Constants.DISABLE) {
            throw new BuzException("操作者不存在或者被禁用了");
        }
    }
}
